]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
js/ui: Choose some actors to cache on the GPU
authorDaniel van Vugt <daniel.van.vugt@canonical.com>
Fri, 6 Apr 2018 10:26:58 +0000 (18:26 +0800)
committerJonas Ådahl <jadahl@gmail.com>
Mon, 27 Aug 2018 14:16:59 +0000 (14:16 +0000)
Flag some actors that are good candidates for caching in texture memory
(what Clutter calls "offscreen redirect"), thereby mostly eliminating
their repaint overhead.

This isn't exactly groundbreaking, it's how you're meant to use
OpenGL in the first place. But the difficulty is in the design of
Clutter which has some peculiarities making universal caching
inefficient at the moment:

 * Repainting an offscreen actor is measurably slower than repainting
   the same actor if it was uncached. But only by less than 100%,
   so if an actor can avoid changing every frame then caching is usually
   more efficient over that timeframe.

 * The cached painting from a container typically includes its children,
   so you can't cache containers whose children are usually animating at
   full frame rate. That results in a performance loss.
     This could be remedied in future by Clutter explicitly separating a
   container's background painting from its child painting and always
   caching the background (as StWidget tries to in some cases already).

So this commit selects just a few areas where caching has been verified
to be beneficial, and many use cases now see their CPU usage halved:

One small window active...... 10% -> 7% (-30%)
...under a panel menu........ 23% -> 9% (-61%)
One maximized window active.. 12% -> 9% (-25%)
...under a panel menu........ 23% -> 11% (-52%)
...under a shell dialog...... 22% -> 12% (-45%)
...in activities overview.... 32% -> 17% (-47%)
(on an i7-7700)

Also a couple of bugs are fixed by this:

https://bugzilla.gnome.org/show_bug.cgi?id=792634
https://bugzilla.gnome.org/show_bug.cgi?id=792633

js/ui/boxpointer.js
js/ui/dash.js
js/ui/dialog.js
js/ui/panel.js

index 47f718a845e2ab2ecf6711cc55191521cef4bf2a..d51877d18035bf3b56f1acd27b0f0fd407c70389 100644 (file)
@@ -44,6 +44,7 @@ var BoxPointer = new Lang.Class({
                                   y_fill: true });
         this._container = new Shell.GenericContainer();
         this.actor.set_child(this._container);
+        this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
         this._container.connect('get-preferred-width', this._getPreferredWidth.bind(this));
         this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this));
         this._container.connect('allocate', this._allocate.bind(this));
index 5ee2476e34a900f699d932303b5c816688b217d3..9b8bfdd135084d7126a4f31ac0a3d5cdd9629b6b 100644 (file)
@@ -402,6 +402,7 @@ var Dash = new Lang.Class({
                                        clip_to_allocation: true });
         this._box._delegate = this;
         this._container.add_actor(this._box);
+        this._container.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
 
         this._showAppsIcon = new ShowAppsIcon();
         this._showAppsIcon.childScale = 1;
index cfa192db73eaa94fc1bccaa61337c1fc9a429851..0dd33706b8bc569824da817e97bf40e5c410b1a1 100644 (file)
@@ -40,6 +40,7 @@ var Dialog = new Lang.Class({
         // mode accordingly so wrapped labels are handled correctly during
         // size requests.
         this._dialog.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH;
+        this._dialog.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
 
         this.contentLayout = new St.BoxLayout({ vertical: true,
                                                 style_class: "modal-dialog-content-box" });
index 05241abdccb9c899021a043cec0c61d4a837b6a5..4fd599c47b604fca232ba343ecc4a282a542eabb 100644 (file)
@@ -776,6 +776,7 @@ var Panel = new Lang.Class({
         this.actor = new Shell.GenericContainer({ name: 'panel',
                                                   reactive: true });
         this.actor._delegate = this;
+        this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
 
         this._sessionStyle = null;